﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace PlanB.Core.Helpers
{
    /// <summary>
    /// Reflection-related helper methods
    /// </summary>
    public static class ReflectionHelpers
    {
        /// <summary>
        /// Retrieves the Assembly from the qualified Assembly Name. 
        /// It also takes the local folder and GAC in consideration
        /// </summary>
        /// <param name="qualifiedAssemblyName">Fully qualified assembly name string</param>
        /// <returns>Asselbly</returns>
        public static Assembly GetAssembly(string qualifiedAssemblyName)
        {
            try
            {
                //
                //extract the assembly and class names from the full qualified assembly name
                string[] parts = qualifiedAssemblyName.Split(',');
                string assemblyName = parts[1].Trim();

                //
                // create an instance of the class from the assembly
                System.Reflection.Assembly assembly = null;

                //
                //first try to load the assembly from the BIN directory
                string localDll = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyName + ".dll");
                string binDll = System.IO.Path.Combine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"), assemblyName + ".dll");

                if (System.IO.File.Exists(localDll))
                {
                    //first check if the assembly exists in the executing directory
                    assembly = System.Reflection.Assembly.LoadFrom(localDll);
                }
                else if (System.IO.File.Exists(binDll))
                {
                    //if assembly is not in the executing directory, try to look in the bin folder under in - necessary for services
                    assembly = System.Reflection.Assembly.LoadFrom(binDll);
                }

                //
                //if that didn't work, try to load it from GAC
                if (assembly == null)
                {
                    try
                    {
                        assembly = System.Reflection.Assembly.Load(qualifiedAssemblyName);
                    }
                    catch (Exception ex)
                    {
                        //TODO: CHANGE WITH REAL EXCEPTION
                        throw new ApplicationException("Could not load assembly.", ex);
                    }
                }
                return assembly;
            }
            catch (Exception ex)
            {
                //TODO: Change with real exceptions
                throw new Exception("Retrieve Assemby Exception", ex);
            }
        }

    }
}
